import classNames from 'classnames';
import React, { useEffect, useMemo, useState } from 'react';
import type { YmAvatarProps } from './interface';

function Avatar(props: YmAvatarProps) {
  const {
    rootClassName,
    rootStyle,
    prefixCls = 'ym-avatar',
    size = 48,
    shape = 'circle',
    src,
    icon,
    children,
    gap = 4,
  } = props;
  const avatarNodeRef = React.useRef<HTMLSpanElement>(null);
  const avatarChildrenRef = React.useRef<HTMLSpanElement>(null);
  const [scale, setScale] = useState<number>(1);

  useEffect(() => {
    let tempScale = 1;
    if (avatarNodeRef.current && avatarChildrenRef.current) {
      const avatarChildrenWidth = avatarChildrenRef.current.offsetWidth;
      const avatarNodeWidth = avatarNodeRef.current.offsetWidth;
      const nodeRemainWidth = avatarNodeWidth - gap * 2;
      if (avatarChildrenWidth > nodeRemainWidth) {
        tempScale = nodeRemainWidth / avatarChildrenWidth;
      }
      setScale(tempScale);
    }
  }, [avatarNodeRef.current, avatarChildrenRef.current, gap]);

  const childrenRender = useMemo<React.ReactNode>(() => {
    let finalChildren: React.ReactNode;
    if (src) {
      //img
      if (React.isValidElement(src)) {
        // React 元素
        finalChildren = src;
      } else {
        //React 节点
        finalChildren = <img src={src as string} alt="avatar" />;
      }
    } else if (icon) {
      //icon
      finalChildren = icon;
    } else if (children) {
      //string
      const childrenStyle = {
        transform: `scale(${scale}) translateX(-50%)`,
        lineHeight: `${size}px`,
      };
      finalChildren = (
        <span
          ref={avatarChildrenRef}
          className={`${prefixCls}-string`}
          style={childrenStyle}
        >
          {children}
        </span>
      );
    }
    return finalChildren;
  }, [src, icon, children, scale, size]);

  const spanClassNames = classNames(
    prefixCls,
    {
      [`${prefixCls}-${shape}`]: !!shape,
      [`${prefixCls}-icon`]: !!icon,
      [`${prefixCls}-img`]: !!src,
    },
    rootClassName,
  );

  const spanStyles = useMemo(() => {
    return {
      width: size,
      height: size,
      lineHeight: `${size}px`,
      fontSize: icon ? size / 2 : 18,
      ...rootStyle,
    };
  }, [size, icon, rootStyle]);

  return (
    <span ref={avatarNodeRef} className={spanClassNames} style={spanStyles}>
      {childrenRender}
    </span>
  );
}

export default Avatar;
